package com.lsh.oms.provider.service.rpc;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.lsh.base.common.json.JsonUtils;
import com.lsh.base.common.model.CommonResult;
import com.lsh.oms.api.model.order.delivery.OrderSendDetailDTO;
import com.lsh.oms.api.model.order.delivery.OrderSendHeadDTO;
import com.lsh.oms.api.service.order.IOrderDeliveryRpcService;
import com.lsh.oms.core.constant.ReturnCode;
import com.lsh.oms.core.enums.OrderStatus;
import com.lsh.oms.core.enums.TaskStatus;
import com.lsh.oms.core.enums.TaskType;
import com.lsh.oms.core.exception.BusinessException;
import com.lsh.oms.core.exception.ExceptionStatus;
import com.lsh.oms.core.model.order.OrderHead;
import com.lsh.oms.core.model.po.OmsTask;
import com.lsh.oms.core.redis.RedisTemplate;
import com.lsh.oms.core.service.order.OrderDeliveryService;
import com.lsh.oms.core.service.order.OrderQueryService;
import com.lsh.oms.core.service.po.OmsTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Project Name: lsh-oms
 *
 * @author peter
 * @date 18/6/23
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Service(protocol = "dubbo", validation = "true", timeout = 10000)
@Slf4j
public class OrderDeliveryRpcServiceImpl implements IOrderDeliveryRpcService {

    @Autowired
    private OrderQueryService orderQueryService;

    @Autowired
    private OrderDeliveryService orderDeliveryService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OmsTaskService omsTaskService;

    @Override
    public CommonResult<Object> create(OrderSendHeadDTO orderSendHeadDTO) {
        String logSign = "logSign order delivery : " + orderSendHeadDTO.getOrder_id();
        long startTimeMs = System.currentTimeMillis();
        CommonResult<Object> commonResult = new CommonResult<>();
        try {
            Integer receiptFlag = orderSendHeadDTO.getReceipt_flag();
            if (null == receiptFlag) {
                receiptFlag = 0;
            }
            if (orderSendHeadDTO == null) {
                throw new BusinessException(ReturnCode.REQUEST_PARAMS_IS_NULL, "请求参数不合法，请检验。");
            }

            log.info(logSign + "【ofc发货入参】 －－ {} ", JsonUtils.obj2Json(orderSendHeadDTO));

            OrderHead orderHead = orderQueryService.findByCode(orderSendHeadDTO.getOrder_id(), true, true);
            if (orderHead == null) {
                log.info(logSign + "请求耗时:" + (startTimeMs - System.currentTimeMillis()) + "ms");
                throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "用户订单号未查询到订单");
            }

            Integer orderStatus = orderHead.getOrderStatus();
            if (orderStatus.compareTo(OrderStatus.ORDER_COMMITING_OFC.getIndex()) < 0) {
                throw new BusinessException(ReturnCode.ORDER_STATUS_ERROR, "订单状态是" + OrderStatus.getName(orderHead.getOrderStatus()) + "，请检验。");
            }
            // TODO 幂等处理
            if (orderStatus >= OrderStatus.ORDER_DELIVERY.getIndex()) {
                commonResult.setCode(ReturnCode.REQUEST_SUCCESS);
                Map<String, Object> respMap = new HashMap<>(6);
                respMap.put("flag", true);
                commonResult.setData(respMap);
                return commonResult;
            }

            List<OrderSendDetailDTO> orderSendHeadDTOItems = orderSendHeadDTO.getItems();
            if (orderSendHeadDTOItems == null || orderSendHeadDTOItems.size() == 0) {
                throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "orderSendHeadDTOItems 必传");
            }
            // TODO
            if (!redisTemplate.lock("oms:delivery:" + orderSendHeadDTO.getOrder_id().toString(), "delivery", 3L)) {
                throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "操作太频繁,请稍后再试");
            }
            commonResult = this.orderDeliveryService.create(orderSendHeadDTO, orderHead, logSign, orderHead.getVenderId());
            log.info("发货完成结果信息 {}", JSON.toJSONString(commonResult));
            if (!commonResult.getCode().equals(ReturnCode.REQUEST_SUCCESS)) {
                throw new BusinessException(ReturnCode.ORDER_STATUS_ERROR, "订单发货失败");
            }

            String msg = commonResult.getMessage();

            if(StringUtils.isNoneBlank(msg) && msg.equals("订单全单捡缺")){
               log.info("订单全单捡缺 处理ok");
            }else {
                this.addPushTmsTask(orderHead);
                if (receiptFlag == 1) {
                    this.addAutoReceipt(orderHead);
                }
            }

        } catch (BusinessException e) {
            commonResult.setCode(e.getCode());
            commonResult.setMessage(e.getMessage());
            log.error("业务异常code : " + e.getCode() + ",异常信息: " + e.getMessage(), e);
        } catch (Exception e) {
            commonResult.setCode(ExceptionStatus.E3001001.getCode());
            commonResult.setMessage(ExceptionStatus.E3001001.getMessage());
            log.error("业务异常code : " + ExceptionStatus.E3001001.getCode() + ",异常信息: " + e.getMessage(), e);
        }

        return commonResult;
    }

    private void addPushTmsTask(OrderHead orderHead) {
        OmsTask omsTaskTms = new OmsTask();
        omsTaskTms.setRefCode(orderHead.getOrderCode() + "");
        omsTaskTms.setContent(orderHead.getOrderCode() + "");
        omsTaskTms.setTaskType(TaskType.ORDER_PUSH_TMS.getCode());
        omsTaskTms.setExecCount(0);
        omsTaskTms.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
        omsTaskTms.setVenderId(orderHead.getVenderId());
        omsTaskService.add(omsTaskTms);
    }

    private void addAutoReceipt(OrderHead orderHead) {
        OmsTask omsTask = new OmsTask();
        omsTask.setRefCode(orderHead.getOrderCode() + "");
        omsTask.setContent(orderHead.getOrderCode() + "");
        omsTask.setTaskType(TaskType.ORDER_RECEIPT.getCode());
        omsTask.setExecCount(0);
        omsTask.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
        omsTask.setVenderId(orderHead.getVenderId());

        omsTaskService.add(omsTask);
    }
}
